//
//  MDHNavigationController.m
//  JSTech
//
//  Created by 高得华 on 2019/4/27.
//  Copyright © 2020 华&梅. All rights reserved.
//

#import "MDHNavigationController.h"
#import "MDHViewController.h"
#import "MDHMacro.h"
#import "NSObject+MDHNSObject.h"
#import "JSTech-Swift.h"

@interface MDHNavigationController ()
<
UINavigationControllerDelegate,
UIGestureRecognizerDelegate
>

/// 导航栏分隔线
@property (nonatomic , weak , readwrite) UIImageView * navigationBottomLine;


///当前的 fakeBar
@property (nonatomic, strong) MDHFakeNavigationBar * fakeBar;
///从哪个来的 fakeBar
@property (nonatomic, strong) MDHFakeNavigationBar * fromFakeBar;
///到哪个 的 fakeBar
@property (nonatomic, strong) MDHFakeNavigationBar * toFakeBar;
///fakeSuperView
@property (nonatomic, strong) UIView * fakeSuperView;

//@property (nonatomic, strong) NSKeyValueObservingOptions * fakeFrameObserver;
///poppingVC
@property (nonatomic, weak) UIViewController * poppingVC;

@end

@implementation MDHNavigationController


//MARK: - === 懒加载
///当前的 fakeBar
- (MDHFakeNavigationBar *)fakeBar {
    if (!_fakeBar) {
        _fakeBar = [MDHFakeNavigationBar new];
    }
    return _fakeBar;
}
///从哪个来的 fakeBar
- (MDHFakeNavigationBar *)fromFakeBar {
    if (!_fromFakeBar) {
        _fromFakeBar = [MDHFakeNavigationBar new];
    }
    return _fromFakeBar;
}
///到哪个 的 fakeBar
- (MDHFakeNavigationBar *)toFakeBar {
    if (!_toFakeBar) {
        _toFakeBar = [MDHFakeNavigationBar new];
    }
    return _toFakeBar;
}
///fakeSuperView
- (UIView *)fakeSuperView {
    return self.navigationBar.subviews.firstObject;
}


// 第一次使用这个类调用一次
+ (void)initialize{
    // 2.设置UINavigationBar的主题
    [self _setupNavigationBarTheme];

    // 3.设置UIBarButtonItem的主题
    [self _setupBarButtonItemTheme];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //@weakify(self);
    // 初始化
    //[self _setup];
    //self.interactivePopGestureRecognizer.delegate = self;
    //self.delegate = self;
    
    self.delegate = self;
    self.interactivePopGestureRecognizer.delegate = self;
    [self.interactivePopGestureRecognizer addTarget:self action:@selector(handleinteractivePopGesture:)];
    [self setupNavigationBar];
}

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    if (self.transitionCoordinator) {
        UIViewController * fromVC = [self.transitionCoordinator viewControllerForKey:UITransitionContextFromViewControllerKey];
        if (fromVC) {
            if (fromVC == self.poppingVC) {
                [self dh_updateNavigationBar:fromVC];
            }
        }
    }else{
        if (self.topViewController) {
            [self dh_updateNavigationBar:self.topViewController];
        }
    }
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    [self layoutFakeSubviews];
}

///popViewController
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
    self.poppingVC = self.topViewController;
    UIViewController * viewController = [super popViewControllerAnimated:animated];
    if (self.topViewController) {
        [self dh_updateNavigationBarTint:self.topViewController ignoreTintColor:true];
    }
    return viewController;
}
///popToRootViewController
- (NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated {
    self.poppingVC = self.topViewController;
    NSArray * vcArray = [super popToRootViewControllerAnimated:animated];
    if (self.topViewController) {
        [self dh_updateNavigationBarTint:self.topViewController ignoreTintColor:true];
    }
    return vcArray;
}
///popToViewController
- (NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated {
    self.poppingVC = self.topViewController;
    NSArray * vcArray = [super popToViewController:viewController animated:animated];
    if (self.topViewController) {
        [self dh_updateNavigationBarTint:self.topViewController ignoreTintColor:true];
    }
    return vcArray;
}


/// 设置导航栏
- (void)setupNavigationBar {
    [self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
    self.navigationBar.shadowImage = [UIImage new];
    [self setupFakeSubviews];
}
///setupFakeSubviews
- (void)setupFakeSubviews {
    if (self.fakeSuperView) {
        if (self.fakeBar.superview == nil) {
            /*fakeFrameObserver = fakeSuperView.observe(\.frame, changeHandler: { [weak self] (obj, changed) in
                guard let `self` = self else { return }
                self.layoutFakeSubviews()
            })*/
            @try {
                [self.fakeSuperView removeObserver:self forKeyPath:@"frame"];
            } @catch (NSException *exception) {
                
            }
            [self.fakeSuperView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
            [self.fakeSuperView insertSubview:self.fakeBar atIndex:0];
        }
    }
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"frame"]) {
        [self layoutFakeSubviews];
    }
}

///layoutFakeSubviews
- (void)layoutFakeSubviews {
    if (self.fakeSuperView) {
        self.fakeBar.frame = self.fakeSuperView.bounds;
        [self.fakeBar setNeedsLayout];
    }
}
///
- (void)handleinteractivePopGesture:(UIScreenEdgePanGestureRecognizer*)gesture {
    if (self.transitionCoordinator) {
        UIViewController * fromVC = [self.transitionCoordinator viewControllerForKey:UITransitionContextFromViewControllerKey];
        UIViewController * toVC = [self.transitionCoordinator viewControllerForKey:UITransitionContextToViewControllerKey];
        if (fromVC && toVC && gesture.state == UIGestureRecognizerStateChanged) {
            self.navigationBar.tintColor = [self average:fromVC.dh_tintColor :toVC.dh_tintColor :self.transitionCoordinator.percentComplete];
        }
    }
}

/// 两个视图的过渡
- (UIColor *)average:(UIColor *)fromColor :(UIColor *)toColor :(CGFloat)percent {
    CGFloat fromRed = 0;
    CGFloat fromGreen = 0;
    CGFloat fromBlue = 0;
    CGFloat fromAlpha = 0;
    [fromColor getRed:&fromRed green:&fromGreen blue:&fromBlue alpha:&fromAlpha];
    CGFloat toRed = 0;
    CGFloat toGreen = 0;
    CGFloat toBlue = 0;
    CGFloat toAlpha = 0;
    [toColor getRed:&toRed green:&toGreen blue:&toBlue alpha:&toAlpha];
    CGFloat red = fromRed + (toRed - fromRed) * percent;
    CGFloat green = fromGreen + (toGreen - fromGreen) * percent;
    CGFloat blue = fromBlue + (toBlue - fromBlue) * percent;
    CGFloat alpha = fromAlpha + (toAlpha - fromAlpha) * percent;
    return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}

///resetButtonLabels
- (void)resetButtonLabels:(UIView *)view1 {
    NSString * viewClassName = [[view1.classForCoder description] stringByReplacingOccurrencesOfString:@"_" withString:@""];
    if ([viewClassName isEqualToString:@"UIButtonLabel"]) {
        view1.alpha = 1;
    } else {
        for (UIView * subview in view1.subviews) {
            [self resetButtonLabels:subview];
        }
    }
}
- (CGRect)fakerBarFrame:(UIViewController *)viewController {
    if (self.fakeSuperView) {
        CGRect frame = [self.navigationBar convertRect:self.fakeSuperView.frame toView:viewController.view];
        frame.origin.x = viewController.view.frame.origin.x;
        return frame;
    }
    return self.navigationBar.frame;
    
}

///showTempFakeBar
- (void)showTempFakeBar:(UIViewController *)fromVC :(UIViewController *)toVC {
    [UIView setAnimationsEnabled:false];
    self.fakeBar.alpha = 0;
    // from
    [fromVC.view addSubview:self.fromFakeBar];
    self.fromFakeBar.frame = [self fakerBarFrame:fromVC];
    [self.fromFakeBar setNeedsLayout];
    [self.fromFakeBar dh_updateFakeBarBackground:fromVC];
    [self.fromFakeBar dh_updateFakeBarShadow:fromVC];
    // to
    [toVC.view addSubview:self.toFakeBar];
    self.toFakeBar.frame = [self fakerBarFrame:toVC];
    [self.toFakeBar setNeedsLayout];
    [self.toFakeBar dh_updateFakeBarBackground:toVC];
    [self.toFakeBar dh_updateFakeBarShadow:toVC];
    [UIView setAnimationsEnabled:true];
}

///clearTempFakeBar
- (void)clearTempFakeBar{
    self.fakeBar.alpha = 1;
    [self.fromFakeBar removeFromSuperview];
    [self.toFakeBar removeFromSuperview];
}

///showViewController
- (void)showViewController:(UIViewController *)vc coordinator:(id <UIViewControllerTransitionCoordinator>)coordinator {
    UIViewController * fromVC = [self.transitionCoordinator viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController * toVC = [self.transitionCoordinator viewControllerForKey:UITransitionContextToViewControllerKey];
    if (fromVC && toVC) {
        [self resetButtonLabels:self.navigationBar];
        [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
            [self dh_updateNavigationBarTint:vc ignoreTintColor:context.interactive];
            if (vc == toVC) {
                [self showTempFakeBar:fromVC :toVC];
            } else {
                [self dh_updateNavigationBarBackground:vc];
                [self dh_updateNavigationBarShadow:vc];
            }
        } completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
            if (context.cancelled) {
                [self dh_updateNavigationBar:fromVC];
            } else {
                [self dh_updateNavigationBar:vc];
            }
            if (vc == toVC) {
                [self clearTempFakeBar];
            }
        }];
    }
}

//MARK: - ==== UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    if (self.transitionCoordinator) {
        [self showViewController:viewController coordinator:self.transitionCoordinator];
    }else{
        if (!animated && self.viewControllers.count > 1) {
            UIViewController * lastButOneVC = self.viewControllers[self.viewControllers.count-2];
            [self showTempFakeBar:lastButOneVC :viewController];
            return;
        }
        [self dh_updateNavigationBar:viewController];
    }
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    if (!animated) {
        [self dh_updateNavigationBar:viewController];
        [self clearTempFakeBar];
    }
    self.poppingVC = nil;
}

//MARK: - ===== UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if (self.viewControllers.count <= 1) {
        return false;
    }
    if (self.topViewController) {
        return self.topViewController.dh_enablePopGesture;
    }
    return true;
}

///
/// 更新导航栏
- (void)dh_updateNavigationBar:(UIViewController *_Nonnull)viewController {
    [self setupFakeSubviews];
    [self dh_updateNavigationBarTint:viewController ignoreTintColor:false];
    [self dh_updateNavigationBarBackground:viewController];
    [self dh_updateNavigationBarShadow:viewController];
}
/// 更新文字、title颜色 是否要 忽略 颜色
- (void)dh_updateNavigationBarTint:(UIViewController *)viewController ignoreTintColor:(BOOL)ignore {
    if (viewController != self.topViewController) {
        return;
    }
    [UIView setAnimationsEnabled:false];
    self.navigationBar.barStyle = viewController.dh_barStyle;
    NSDictionary * titleTextAttributes = @{
        NSForegroundColorAttributeName: viewController.dh_titleColor,
        NSFontAttributeName:viewController.dh_titleFont,
    };
    self.navigationBar.titleTextAttributes = titleTextAttributes;
    if (!ignore) {
        self.navigationBar.tintColor = viewController.dh_tintColor;
    }
    [UIView setAnimationsEnabled:true];
}

/// 更新背景颜色
- (void)dh_updateNavigationBarBackground:(UIViewController *_Nonnull)viewController {
    if (viewController != self.topViewController) {
        return;
    }
    [self.fakeBar dh_updateFakeBarBackground:viewController];
}
/// 导航栏 分界线
- (void)dh_updateNavigationBarShadow:(UIViewController *_Nonnull)viewController {
    if (viewController != self.topViewController) {
        return;
    }
    [self.fakeBar dh_updateFakeBarShadow:viewController];
}



#pragma mark - 初始化
- (void) _setup
{
    [self _setupNavigationBarBottomLine];
}

// 查询最后一条数据
- (UIImageView *)_findHairlineImageViewUnder:(UIView *)view{
    if ([view isKindOfClass:UIImageView.class] && view.bounds.size.height <= 1.0) {
        return (UIImageView *)view;
    }
    for (UIView *subview in view.subviews){
        UIImageView *imageView = [self _findHairlineImageViewUnder:subview];
        if (imageView){ return imageView; }
    }
    return nil;
}

#pragma mark - 设置导航栏的分割线
- (void)_setupNavigationBarBottomLine {
    //!!!:这里之前设置系统的 navigationBarBottomLine.image = xxx;无效 Why？ 隐藏了系统的 自己添加了一个分割线
    // 隐藏系统的导航栏分割线
    UIImageView *navigationBarBottomLine = [self _findHairlineImageViewUnder:self.navigationBar];
    navigationBarBottomLine.hidden = true;
    // 添加自己的分割线
    CGFloat navSystemLineH = .5f;
    UIImageView *navSystemLine = [[UIImageView alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(self.navigationBar.bounds), [UIScreen mainScreen].bounds.size.width, navSystemLineH)];
    navSystemLine.backgroundColor = kColor_MDHHex(@"#F5F5F5");
    [self.navigationBar addSubview:navSystemLine];
    self.navigationBottomLine = navSystemLine;
}


/**
 *  设置UINavigationBarTheme的主题
 */
+ (void) _setupNavigationBarTheme {
    UINavigationBar *appearance = [UINavigationBar appearance];
    
    /// 设置背景
    //!!!: 必须设置为透明  不然布局有问题 ios8以下  会崩溃/ 如果iOS8以下  请再_setup里面 设置透明 self.navigationBar.translucent = YES;
    appearance.translucent = true;
    //[appearance setTranslucent:true]; /// 必须设置true
    
    // 设置导航栏的样式
    [appearance setBarStyle:UIBarStyleDefault];
    //设置导航栏文字按钮的渲染色
    [appearance setTintColor:kColor_MDHDarkModeStr(@"#000000", @"#FFFFFF")];
    // 设置导航栏的背景渲染色
    //CGFloat rgb = 0.1;[UIColor colorWithRed:rgb green:rgb blue:rgb alpha:0.65]
    [appearance setBarTintColor:kColor_MDHDarkModeStr(@"#FFFFFF", @"#000000")];
    // 设置文字属性
    NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
    textAttrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:17.0f];
    textAttrs[NSForegroundColorAttributeName] = kColor_MDHDarkModeStr(@"#000000", @"#FFFFFF");
    
    // UIOffsetZero是结构体, 只要包装成NSValue对象, 才能放进字典\数组中
    NSShadow *shadow = [[NSShadow alloc] init];
    shadow.shadowOffset =  CGSizeZero;
    textAttrs[NSShadowAttributeName] = shadow;
    [appearance setTitleTextAttributes:textAttrs];
    
    /// 去掉导航栏的阴影图片
    [appearance setShadowImage:[UIImage new]];
    
    ///返回按钮[backButtonImage ]
    UIImage * backButtonImage = [[UIImage imageNamed:kCommonNavButtonBack] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];//[[[UIImage imageNamed:kCommonNavButtonBack] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
    appearance.backIndicatorImage = backButtonImage;
    appearance.backIndicatorTransitionMaskImage = backButtonImage;
    
    if (@available(iOS 11.0, *)) {
        //大标题
        appearance.prefersLargeTitles = false;
    } else {
        // Fallback on earlier versions
    }
}

/**
 *  设置UIBarButtonItem的主题
 */
+ (void)_setupBarButtonItemTheme {
    // 通过appearance对象能修改整个项目中所有UIBarButtonItem的样式
    UIBarButtonItem * appearance = [UIBarButtonItem appearance];
    
    CGFloat fontSize = 15.0f;
    /**设置文字属性**/
    // 设置普通状态的文字属性
    NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
    textAttrs[NSForegroundColorAttributeName] = [UIColor blackColor];
    textAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:fontSize];
    NSShadow *shadow = [[NSShadow alloc] init];
    shadow.shadowOffset =  CGSizeZero;
    textAttrs[NSShadowAttributeName] = shadow;
    [appearance setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
    
    // 设置高亮状态的文字属性
    NSMutableDictionary *highTextAttrs = [NSMutableDictionary dictionaryWithDictionary:textAttrs];
    highTextAttrs[NSForegroundColorAttributeName] = [[UIColor blackColor] colorWithAlphaComponent:.5f];
    [appearance setTitleTextAttributes:highTextAttrs forState:UIControlStateHighlighted];
    
    // 设置不可用状态(disable)的文字属性
    NSMutableDictionary *disableTextAttrs = [NSMutableDictionary dictionaryWithDictionary:textAttrs];
    disableTextAttrs[NSForegroundColorAttributeName] = [[UIColor blackColor] colorWithAlphaComponent:.5f];
    [appearance setTitleTextAttributes:disableTextAttrs forState:UIControlStateDisabled];
}


#pragma mark - Publi Method
/// 显示导航栏的细线
- (void)showNavigationBottomLine { self.navigationBottomLine.hidden = false; }
/// 隐藏导航栏的细线
- (void)hideNavigationBottomLine{ self.navigationBottomLine.hidden = true; }


/// 能拦截所有push进来的子控制器
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    NSString * title = @"";
    // 如果现在push的不是栈底控制器(最先push进来的那个控制器)
    if (self.viewControllers.count > 0) {
        /// 隐藏底部tabbar
        viewController.hidesBottomBarWhenPushed = true;
        /// eg: [A push B]
        /// 1.取出当前的控制器的title ， 也就是取出 A.title
        /// CoderMikeHe Fixed: [[self topViewController] navigationItem].title 这样来获取title 而不是[[self topViewController] title]
        //title = [[self topViewController] navigationItem].title?:@"返回";
        
        /// 2.判断要被Push的控制器（B）是否是 MHViewController ，
        if ([viewController isKindOfClass:[MDHViewController class]]) {
            MDHViewModel *viewModel = [(MDHViewController *)viewController viewModel];
            /// 3. 查看backTitle 是否有值
            title = viewModel.backTitle?:title;
        }
        // 4.这里可以设置导航栏的左右按钮 统一管理方法
        //viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem mh_backItemWithTitle:title imageName:@"barbuttonicon_back_15x30" target:self action:@selector(_back)];
    }
    viewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStylePlain target:nil action:nil];
    // push
    [super pushViewController:viewController animated:animated];
    //是否是最顶上的 视图 也就是说是否是 Tabbar的一级
    [self navigation_top_vc];
}
/// 事件处理
- (void)_back {
    [self popViewControllerAnimated:true];
}

/*
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
    //是否是最顶上的 视图 也就是说是否是 Tabbar的一级
    [self navigation_top_vc];
    return [super popViewControllerAnimated:animated];
}

- (NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated {
    //是否是最顶上的 视图 也就是说是否是 Tabbar的一级
    [self navigation_top_vc];
    return [super popToRootViewControllerAnimated:animated];
}

- (NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated {
    //是否是最顶上的 视图 也就是说是否是 Tabbar的一级
    [self navigation_top_vc];
    return [super popToViewController:viewController animated:animated];
}*/

///是否是最顶上的 视图 也就是说是否是 Tabbar的一级
- (void)navigation_top_vc {
    
}

#pragma mark - Override
- (BOOL)shouldAutorotate {
    return self.topViewController.shouldAutorotate;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
    return self.topViewController.supportedInterfaceOrientations;
}

- (UIStatusBarStyle)preferredStatusBarStyle{
    return self.topViewController.preferredStatusBarStyle;
}

- (BOOL)prefersStatusBarHidden{
    return self.topViewController.prefersStatusBarHidden;
}

#pragma mark - 按钮
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
    if([self.viewControllers count] < [navigationBar.items count]) {
        return YES;
    }
    
    BOOL shouldPop = YES;
    UIViewController * vc = [self topViewController];
    if([vc respondsToSelector:@selector(navigationShouldPopOnBackButton)]) {
        shouldPop = [vc navigationShouldPopOnBackButton];
    }
    
    if(shouldPop) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self popViewControllerAnimated:YES];
        });
    } else {
        for(UIView *subview in [navigationBar subviews]) {
            if(0. < subview.alpha && subview.alpha < 1.0) {
                [UIView animateWithDuration:0.25 animations:^{
                    subview.alpha = 1.0;
                }];
            }
        }
    }
    return false;
}
///
//- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer {
//    if (self.viewControllers.count <= 1) {
//        return false;
//    } else {
//        return true;
//    }
//    //return [[FloatViewManager manager] mdh_gestureRecognizerShouldBegin:gestureRecognizer];
//}
/*
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
    return [[FloatViewManager manager] mdh_navigationController:navigationController animationControllerFor:operation from:fromVC to:toVC];
}*/

@end






//MARK: - ==== viewController 的 NavigationBar
//@interface UIViewController (MDHNavigationBar)
//@end
@implementation UIViewController (MDHNavigationBar)

@dynamic dh_barStyle, dh_tintColor, dh_titleColor, dh_titleFont, dh_backgroundColor, dh_backgroundImage, dh_barAlpha, dh_shadowHidden, dh_shadowColor, dh_enablePopGesture;

/// 导航栏样式，默认样式
- (void)setDh_barStyle:(UIBarStyle)dh_barStyle {
    objc_setAssociatedObject(self, @selector(dh_barStyle), @(dh_barStyle), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self dh_setNeedsNavigationBarTintUpdate];
}
- (UIBarStyle)dh_barStyle {
    NSNumber * ss_num = objc_getAssociatedObject(self, @selector(dh_barStyle));
    if (ss_num == nil) {
        return [UINavigationBar appearance].barStyle;
    }
    return [ss_num intValue];
}

/// 导航栏前景色（item的文字图标颜色），默认黑色
- (void)setDh_tintColor:(UIColor *)dh_tintColor {
    objc_setAssociatedObject(self, @selector(dh_tintColor), dh_tintColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self dh_setNeedsNavigationBarTintUpdate];
}
- (UIColor *)dh_tintColor {
    UIColor * color = objc_getAssociatedObject(self, @selector(dh_tintColor));
    if (color) return color;
    color = [UINavigationBar appearance].tintColor;
    if (color) return color;
    return [UIColor blackColor];
}

/// 导航栏标题文字颜色，默认黑色
- (void)setDh_titleColor:(UIColor *)dh_titleColor {
    objc_setAssociatedObject(self, @selector(dh_titleColor), dh_titleColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self dh_setNeedsNavigationBarTintUpdate];
}
- (UIColor *)dh_titleColor {
    UIColor * color = objc_getAssociatedObject(self, @selector(dh_titleColor));
    if (color) return color;
    color = [UINavigationBar appearance].titleTextAttributes[NSForegroundColorAttributeName];
    if (color) return color;
    return [UIColor blackColor];
}

/// 导航栏标题文字字体，默认17号粗体
- (void)setDh_titleFont:(UIFont *)dh_titleFont {
    objc_setAssociatedObject(self, @selector(dh_titleFont), dh_titleFont, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self dh_setNeedsNavigationBarTintUpdate];
}
- (UIFont *)dh_titleFont {
    UIFont * font = objc_getAssociatedObject(self, @selector(dh_titleFont));
    if (font) return font;
    font = [UINavigationBar appearance].titleTextAttributes[NSFontAttributeName];
    if (font) return font;
    return [UIFont boldSystemFontOfSize:17];
}

/// 导航栏背景色，默认白色
- (void)setDh_backgroundColor:(UIColor *)dh_backgroundColor {
    objc_setAssociatedObject(self, @selector(dh_backgroundColor), dh_backgroundColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self dh_setNeedsNavigationBarBackgroundUpdate];
    
}
- (UIColor *)dh_backgroundColor {
    UIColor * backgroundColor = objc_getAssociatedObject(self, @selector(dh_backgroundColor));
    if (backgroundColor) return backgroundColor;
    backgroundColor = [UINavigationBar appearance].barTintColor;
    if (backgroundColor) return backgroundColor;
    return [UIColor whiteColor];
}

/// 导航栏背景图片
- (void)setDh_backgroundImage:(UIImage *)dh_backgroundImage {
    objc_setAssociatedObject(self, @selector(dh_backgroundImage), dh_backgroundImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self dh_setNeedsNavigationBarBackgroundUpdate];
}
- (UIImage *)dh_backgroundImage {
    UIImage * image = objc_getAssociatedObject(self, @selector(dh_backgroundImage));
    if (image) {
        return image;
    }else{
        image = [[UINavigationBar appearance] backgroundImageForBarMetrics:UIBarMetricsDefault];
        return image;
    }
}

/// 导航栏背景透明度，默认1
- (void)setDh_barAlpha:(CGFloat)dh_barAlpha {
    objc_setAssociatedObject(self, @selector(dh_barAlpha), @(dh_barAlpha), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self dh_setNeedsNavigationBarBackgroundUpdate];
}
- (CGFloat)dh_barAlpha {
    NSNumber * ss_num = objc_getAssociatedObject(self, @selector(dh_barAlpha));
    if (ss_num == nil) {
        return 1;
    }
    return [ss_num floatValue];
}

/// 导航栏底部分割线是否隐藏，默认不隐藏
- (void)setDh_shadowHidden:(BOOL)dh_shadowHidden {
    objc_setAssociatedObject(self, @selector(dh_shadowHidden), @(dh_shadowHidden), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self dh_setNeedsNavigationBarShadowUpdate];
}
- (BOOL)dh_shadowHidden {
    NSNumber * ss_num = objc_getAssociatedObject(self, @selector(dh_shadowHidden));
    if (ss_num == nil) {
        return false;
    }
    return ss_num.boolValue;
}

/// 导航栏底部分割线颜色
- (void)setDh_shadowColor:(UIColor *)dh_shadowColor {
    objc_setAssociatedObject(self, @selector(dh_shadowColor), dh_shadowColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self dh_setNeedsNavigationBarShadowUpdate];
}
- (UIColor *)dh_shadowColor {
    UIColor * backgroundColor = objc_getAssociatedObject(self, @selector(dh_shadowColor));
    if (backgroundColor) return backgroundColor;
    return [[UIColor grayColor] colorWithAlphaComponent:0.1];
}

/// 是否开启手势返回，默认开启
- (void)setDh_enablePopGesture:(BOOL)dh_enablePopGesture {
    objc_setAssociatedObject(self, @selector(dh_enablePopGesture), @(dh_enablePopGesture), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)dh_enablePopGesture {
    NSNumber * ss_num = objc_getAssociatedObject(self, @selector(dh_enablePopGesture));
    if (ss_num == nil) {
        return true;
    }
    return ss_num.boolValue;
}


// MARK: -  更新UI
// 整体更新
- (void) dh_setNeedsNavigationBarUpdate {
    if ([self.navigationController isKindOfClass:[MDHNavigationController class]]) {
        [((MDHNavigationController *)self.navigationController) dh_updateNavigationBar:self];
    }
}
// 更新文字、title颜色
- (void) dh_setNeedsNavigationBarTintUpdate {
    if ([self.navigationController isKindOfClass:[MDHNavigationController class]]) {
        [((MDHNavigationController *)self.navigationController) dh_updateNavigationBarTint:self ignoreTintColor:false];
    }
}
// 更新背景
- (void) dh_setNeedsNavigationBarBackgroundUpdate {
    if ([self.navigationController isKindOfClass:[MDHNavigationController class]]) {
        [((MDHNavigationController *)self.navigationController) dh_updateNavigationBarBackground:self];
    }
}
// 更新shadow
- (void) dh_setNeedsNavigationBarShadowUpdate {
    if ([self.navigationController isKindOfClass:[MDHNavigationController class]]) {
        [((MDHNavigationController *)self.navigationController) dh_updateNavigationBarShadow:self];
    }
}

@end





@interface MDHFakeNavigationBar ()

/// 背景视图
@property (nonatomic, strong) UIImageView * fakeBackgroundImageView;
/// 毛玻璃
@property (nonatomic, strong) UIVisualEffectView * fakeBackgroundEffectView;
/// 分界线
@property (nonatomic, strong) UIImageView * fakeShadowImageView;

@end

@implementation MDHFakeNavigationBar

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self setupView];
    }
    return self;
}

// 设置页面的布局
- (void)setupView {
    self.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.0001];
    [self addSubview:self.fakeBackgroundEffectView];
    [self addSubview:self.fakeBackgroundImageView];
    [self addSubview:self.fakeShadowImageView];
}

// 设置大小
- (void)layoutSubviews {
    [super layoutSubviews];
    self.fakeBackgroundEffectView.frame = self.bounds;
    self.fakeBackgroundImageView.frame = self.bounds;
    self.fakeShadowImageView.frame = CGRectMake(0, CGRectGetHeight(self.bounds)-0.5, CGRectGetWidth(self.bounds), 0.5);
}

//MARK: - === 对外暴露的方法
/// 设置背景的颜色
- (void) dh_updateFakeBarBackground:(UIViewController *)viewController {
    UIView * view1 = self.fakeBackgroundEffectView.subviews.lastObject;
    if (view1) {
        view1.backgroundColor = viewController.dh_backgroundColor;
    }
    self.fakeBackgroundImageView.image = viewController.dh_backgroundImage;
    if (viewController.dh_backgroundImage != nil) {
        // 直接使用fakeBackgroundEffectView.alpha控制台会有提示
        // 这样使用避免警告
        for (UIView * view1 in self.fakeBackgroundEffectView.subviews) {
            view1.alpha = 0;
        }
    } else {
        for (UIView * view1 in self.fakeBackgroundEffectView.subviews) {
            view1.alpha = viewController.dh_barAlpha;
        }
    }
    self.fakeBackgroundImageView.alpha = viewController.dh_barAlpha;
    self.fakeShadowImageView.alpha = viewController.dh_barAlpha;
}

/// 是否显示 分界线
- (void) dh_updateFakeBarShadow:(UIViewController *)viewController {
    self.fakeShadowImageView.hidden = viewController.dh_shadowHidden;
    self.fakeShadowImageView.backgroundColor = viewController.dh_shadowColor;
}

//MARK: - === 懒加载
/// 背景视图
- (UIImageView *)fakeBackgroundImageView {
    if (!_fakeBackgroundImageView) {
        UIImageView * imv = [UIImageView new];
        _fakeBackgroundImageView = imv;
        imv.userInteractionEnabled = false;
        imv.contentScaleFactor = 1;
        imv.contentMode = UIViewContentModeScaleToFill;
        imv.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.0001];
    }
    return _fakeBackgroundImageView;
}
/// 毛玻璃
- (UIVisualEffectView *)fakeBackgroundEffectView {
    if (!_fakeBackgroundEffectView) {
        UIVisualEffectView * fakeBackgroundEffectView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
        _fakeBackgroundEffectView = fakeBackgroundEffectView;
        fakeBackgroundEffectView.userInteractionEnabled = false;
    }
    return _fakeBackgroundEffectView;
}
/// 分界线
- (UIImageView *)fakeShadowImageView {
    if (!_fakeShadowImageView) {
        UIImageView * fakeShadowImageView = [UIImageView new];
        _fakeShadowImageView = fakeShadowImageView;
        fakeShadowImageView.userInteractionEnabled = false;
        fakeShadowImageView.contentScaleFactor = 1;
    }
    return _fakeShadowImageView;
}

@end
